﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TestcraftLibrary.CVar
{
    [Flags]
    public enum CVarFlags : ushort
    {
        CVarFlag_Float = 1,
        CVarFlag_Int = 2,
        CVarFlag_String = 4,
        CVarFlag_Bool = 8,
        CVarFlag_Persistent = 16,
        CVarFlag_Immutable = 32
    }

    public class CVarSystem : IEnumerable<CVar>
    {


        private LinkedList<CVar> cvars;

        public string PersistentStoreLocation { get; set; }

        public CVarSystem()
        {
            this.cvars = new LinkedList<CVar>();
        }

        public void Startup()
        {
            if (!string.IsNullOrWhiteSpace(PersistentStoreLocation))
            {
                if (!System.IO.Directory.Exists(PersistentStoreLocation))
                    System.IO.Directory.CreateDirectory(PersistentStoreLocation);

                string persistentDataPath = System.IO.Path.Combine(PersistentStoreLocation, "cvar.bin");
                if (System.IO.File.Exists(persistentDataPath))
                {
                    System.IO.FileStream stream = null;
                    System.IO.BinaryReader reader;
                    try
                    {
                        stream = new System.IO.FileStream(persistentDataPath, System.IO.FileMode.Open);
                        reader = new System.IO.BinaryReader(stream);
                        while (reader.BaseStream.Position < reader.BaseStream.Length - 1)
                        {
                            this.cvars.AddLast(CVar.DeserializeFromStream(reader));
                        }
                    }
                    finally
                    {
                        if (stream != null)
                        {
                            stream.Close();
                            stream.Dispose();
                        }
                    }
                }
            }
        }

        public void Shutdown()
        {
            if (!string.IsNullOrWhiteSpace(PersistentStoreLocation))
            {
                if (!System.IO.Directory.Exists(PersistentStoreLocation))
                    System.IO.Directory.CreateDirectory(PersistentStoreLocation);

                string persistentDataPath = System.IO.Path.Combine(PersistentStoreLocation, "cvar.bin");

                System.IO.FileStream stream = null;
                System.IO.BinaryWriter writer;
                try
                {
                    stream = new System.IO.FileStream(persistentDataPath, System.IO.FileMode.Create);
                    writer = new System.IO.BinaryWriter(stream);
                    foreach (CVar cvar in this.cvars)
                    {
                        if (cvar.IsPersistent)
                        {
                            cvar.SerializeToStream(writer);
                        }
                    }
                }
                finally
                {
                    if (stream != null)
                    {
                        stream.Close();
                        stream.Dispose();
                    }
                }
            }
            
        }

        public CVar Get(string name)
        {
            CVar result = null;
            foreach (CVar cvar in this.cvars)
            {
                if (cvar.Name == name)
                {
                    result = cvar;
                    break;
                }
            }

            return result;
        }

        public void Set(CVar cvar)
        {
            if (this.Get(cvar.Name) == null)
                this.cvars.AddLast(cvar);
        }

        //public void Set(string name, string description, bool immutable, bool persistent, int value)
        //{
        //}

        public IEnumerator<CVar> GetEnumerator()
        {
            return this.cvars.GetEnumerator();
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return this.cvars.GetEnumerator();
        }
    }
}
